<?php

declare(strict_types=1);

namespace app\controller;

use think\exception\ValidateException;
use think\Request;
use think\Validate;

use app\model\User as UserModel;
use app\validate\User as ValidateUser;
use app\validate\Register;

use \Firebase\JWT\JWT;


class User
{

    public function login(Request $request)
    {
        try{
            validate(ValidateUser::class)->check([
                'username'  => $request->param('username'),
                'password' => $request->param('password'),
            ]);

            $users = new UserModel();
            $userinfo = $users->getUser($request);

            list($accessToken,$accessRefreshToken) = $this->createToken($userinfo);
            $data = [
                'token'=>$accessToken,    //验证请求API
                'refreshToken'=>$accessRefreshToken //获取新的Token
            ];

            if(!empty($userinfo)){
                return json($data);
            }
        }catch (ValidateException $e){
            return json(['error'=>$e]);
        }
    }

    public function getUsers(Request $request)
    {
        $userModel = new UserModel();
        $users = $userModel->getUsers();
        return json(['data'=>$users,'code'=>200]);
    }

    public function register(Request $request)
    {
        try{
            $username = $request->param('username');
            $password = $request->param('password');
            validate(Register::class)->check([
                'username'  => $username,
                'password' => $username,
                'captcha'=>$request->param('captcha')
            ]);

            $users = new UserModel();

            $userinfo = $users->where('username',$username)
                ->findOrEmpty()
                ->toArray();

            if(!empty($userinfo)){
                return json(['code'=>'201','msg'=>'该用于已存在']);
            }

            $users->username = $username;
            $users->password = md5($password);
            $users->save();

            $userinfo = [
                'id'=>$users->id,
                'username'=>$username,
                'password'=>$password
            ];

            list($accessToken,$accessRefreshToken) = $this->createToken($userinfo);
            $data = [
                'token'=>$accessToken,    //验证请求API
                'refreshToken'=>$accessRefreshToken //获取新的Token
            ];

            if(!empty($userinfo)){
                return json($data);
            }
        }catch (ValidateException $e){
            return json(['error'=>$e]);
        }
    }


    private function createToken($userinfo)
    {
        $key = md5($userinfo['id'].$userinfo['username'].$userinfo['password']);

        $tokenExtra = time()+60*60*2;//token过期时间两小时
        $accessTokenBody = array(
            "sub"=>$userinfo['username'],
            "iss" => "liyulong",
            "iat" => 1356999524,
            "exp" =>$tokenExtra,
        );

        $accessToken = JWT::encode($accessTokenBody, $key);
        $refreshTokenExtra = $tokenExtra+60*30;//获取新token的过期时间比token的时间多30分钟

        $accessTokenBody['exp'] = $refreshTokenExtra;
        $accessRefreshToken = JWT::encode($accessTokenBody,$key);

        $userModel = new UserModel();
        $user = $userModel->find($userinfo['id']);

        $user->token_expire_time = $tokenExtra;
        $user->refresh_token_expire_time = $refreshTokenExtra;
        $user->token = $accessToken;
        $user->refresh_token = $accessRefreshToken;
        $user->save();

        $token = [$accessToken,$accessRefreshToken];
        return $token;
    }

    public function getToken(Request $request)
    {
        $userModel = new UserModel();

        if(empty($request->header('authorization'))){
            return json(['code'=>401,'msg'=>'not found token']);
        }

        $token = explode(' ',$request->header('authorization'));

        if(!isset($token[1])){
            abort(401,'Unauthorized');
        }

        $userinfo = $userModel->where('refresh_token',$token[1])
                    ->findOrEmpty()
                    ->toArray()
        ;

        if(empty($userinfo)){
            return json(['code'=>404,'msg'=>'not found']);
        }

        if($userinfo['refresh_token_expire_time'] <=time() ){
            abort(40316,'refresh_token已过期，请重新登陆');
        }

        $this->createToken($userinfo);

        list($accessToken,$accessRefreshToken) = $this->createToken($userinfo);
        $data = [
            'token'=>$accessToken,    //验证请求API
            'refreshToken'=>$accessRefreshToken //获取新的Token
        ];

        if(!empty($userinfo)){
            return json($data);
        }
    }

    public function getBasicAuthorized(){
        $UserName = '';
        $PassWord = '';

        //Apache服务器
        if (isset($_SERVER['PHP_AUTH_USER'])) {
            $UserName = $_SERVER['PHP_AUTH_USER'];
            $PassWord = $_SERVER['PHP_AUTH_PW'];
        }elseif(isset($_SERVER['HTTP_AUTHORIZATION'])){//其他服务器如 Nginx  Authorization
            if (strpos(strtolower($_SERVER['HTTP_AUTHORIZATION']), 'basic') === 0) {
                $Authorization = explode(':', base64_decode(substr($_SERVER['HTTP_AUTHORIZATION'], 6)));
                $UserName = isset($Authorization[0])?$Authorization[0]:'';
                $PassWord = isset($Authorization[1])?$Authorization[1]:0;
            }
        }

        return array($UserName,$PassWord);
    }

}
